var assert  =   require("assert");
var Endpoint    =   require("../util/endpoint");
var NetThread   =   require("./netthread");
var CurrentContext  =   require("./currentContext");
var TimeProvider    =   require("../util/timeProvider");
var XError =   require("../util/x-errors-const");

var BindAdapter = function() {
    this._objName   =   "";
    this._servant   =   "";
    this._endpoint  =   undefined;

    this._protocolName  =   "";
    this._protocol      =   undefined;
    this._maxconns      =   1024;
    this._netthread     =   undefined;
    this._handleImp     =   undefined;
}

module.exports  = BindAdapter;

BindAdapter.prototype.__defineGetter__("name", function() { return this._objName; })
BindAdapter.prototype.__defineSetter__("name", function(value) { this._objName = value; })

BindAdapter.prototype.__defineGetter__("servantName", function() { return this._servant; })
BindAdapter.prototype.__defineSetter__("servantName", function(value) { this._servant = value; })

BindAdapter.prototype.__defineGetter__("endpoint", function() { return this._endpoint; })
BindAdapter.prototype.__defineSetter__("endpoint", function(value) { this._endpoint = value; })

BindAdapter.prototype.__defineGetter__("protocolName", function() { return this._protocolName; })
BindAdapter.prototype.__defineSetter__("protocolName", function(value) { this._protocolName = value; })

BindAdapter.prototype.__defineGetter__("protocol", function() { return this._protocol; })
BindAdapter.prototype.__defineSetter__("protocol", function(value) { this._protocol = value; })

BindAdapter.prototype.__defineGetter__("maxconns", function() { return this._maxconns; })
BindAdapter.prototype.__defineSetter__("maxconns", function(value) { this._maxconns = value; })

BindAdapter.prototype.__defineGetter__("handleImp", function() { return this._handleImp; })
BindAdapter.prototype.__defineSetter__("handleImp", function(value) { this._handleImp = value; })

BindAdapter.prototype.start = function() {
    assert(this._endpoint.sProtocol === "tcp" || this._endpoint.sProtocol === "udp", "trans protocol must be tcp or udp");

    this._netthread =   new NetThread(this, this._endpoint, this._protocol);
    this._netthread.initialize();
}

BindAdapter.prototype.stop = function() {
    this._netthread.stop();
}

BindAdapter.prototype.dispatch  = function(transceiver, protoMessage) {
    var current = new CurrentContext();
    current._origin     =   protoMessage.origin;
    current._endpoint   =   new Endpoint(transceiver._socket.remoteAddress, transceiver._socket.remotePort);
    current._adapter    =   this;
    current._transceiver    =   transceiver;
    current._timestamp      =   TimeProvider.nowTimestamp();

    try {
        var func    =   (protoMessage.sFuncName && this._handleImp[protoMessage.sFuncName]) || this._handleImp["doRequest"];
        if(func) {
            func.call(this._handleImp, current, protoMessage.origin);
        }else {
            current.sendErrorResponse(XError.SERVER.FUNC_NOT_FOUND, "Not Found Func By Name:" + protoMessage.sFuncName ? protoMessage.sFuncName : "doRequest");
        }
    } catch(e) {
        current.sendErrorResponse(e.code != undefined ? e.code : XError.SERVER.DECODE_ERROR, "BindAdapter Exception:" + e.message);
    }
}